{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6b2db89d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e42929c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import accuracy_score\n",
    "from sklearn.metrics import f1_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "24555bfe",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Admin\\.conda\\envs\\oldervenv\\Lib\\site-packages\\lightautoml\\transformers\\text.py:22: UserWarning: 'gensim' - package isn't installed\n",
      "  warnings.warn(\"'gensim' - package isn't installed\")\n",
      "C:\\Users\\Admin\\.conda\\envs\\oldervenv\\Lib\\site-packages\\lightautoml\\addons\\interpretation\\l2x.py:23: UserWarning: 'gensim' - package isn't installed\n",
      "  warnings.warn(\"'gensim' - package isn't installed\")\n"
     ]
    }
   ],
   "source": [
    "from lightautoml.automl.presets.text_presets import TabularNLPAutoML\n",
    "from lightautoml.tasks import Task\n",
    "\n",
    "from lightautoml.addons.interpretation import LimeTextExplainer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "98d6d9d3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "09020123",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.cuda.is_available()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "1ddea663",
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers import logging\n",
    "\n",
    "logging.set_verbosity_error()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a74ece2c",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.random.seed(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a7da60f3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>review</th>\n",
       "      <th>sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>45140</th>\n",
       "      <td>Ехала долго посылка, больше полутора месяца. Д...</td>\n",
       "      <td>neautral</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>82647</th>\n",
       "      <td>Очень красивый и приятный на ощупь))</td>\n",
       "      <td>positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>39454</th>\n",
       "      <td>нитки торчат, прошито очень неаккуратно</td>\n",
       "      <td>neautral</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>71219</th>\n",
       "      <td>Доставка быстрая. По размеру подошло 46 р-р. Т...</td>\n",
       "      <td>positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>45132</th>\n",
       "      <td>Пахнет</td>\n",
       "      <td>neautral</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>72801</th>\n",
       "      <td>Отлично всё - пошив, качество, фасон. Брала сп...</td>\n",
       "      <td>positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>67107</th>\n",
       "      <td>Пришли за три недели, на 39 идеально!!! Понрав...</td>\n",
       "      <td>positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1487</th>\n",
       "      <td>Плохое качество и велик размер S. Хотя у меня ...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9131</th>\n",
       "      <td>Прошло 4 месяца с продом.продлевали защиту тов...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3752</th>\n",
       "      <td>Товар так и не пришел! Пришел подарок от продо...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                  review sentiment\n",
       "45140  Ехала долго посылка, больше полутора месяца. Д...  neautral\n",
       "82647              Очень красивый и приятный на ощупь))   positive\n",
       "39454            нитки торчат, прошито очень неаккуратно  neautral\n",
       "71219  Доставка быстрая. По размеру подошло 46 р-р. Т...  positive\n",
       "45132                                            Пахнет   neautral\n",
       "72801  Отлично всё - пошив, качество, фасон. Брала сп...  positive\n",
       "67107  Пришли за три недели, на 39 идеально!!! Понрав...  positive\n",
       "1487   Плохое качество и велик размер S. Хотя у меня ...  negative\n",
       "9131   Прошло 4 месяца с продом.продлевали защиту тов...  negative\n",
       "3752   Товар так и не пришел! Пришел подарок от продо...  negative"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reviews = pd.read_csv('data/reviews.csv.zip', sep='\\t')\n",
    "reviews.drop_duplicates(subset=['review'], inplace=True)\n",
    "reviews.sample(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c0c306a6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sentiment</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>neautral</th>\n",
       "      <td>28812</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>negative</th>\n",
       "      <td>29218</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>positive</th>\n",
       "      <td>29291</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           count\n",
       "sentiment       \n",
       "neautral   28812\n",
       "negative   29218\n",
       "positive   29291"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "full_counts = reviews.groupby('sentiment').agg(count = ('sentiment', 'count'))\n",
    "full_counts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "6bcdfd61",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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FiyolrVfv35wOp1IT0+v1bGIiIhIPbgAp57p9fpqH0uSBKfTCYvFgsjISKSmpl7xOZcLXE2MGTMGubm5eOedd9CkSRMYjUakpKTAarXWKmenTp3QrFkzLF26FE899RSWL1+OBQsWVN1vsVjwxBNPYMKECVd8bkxMTK2ORUREROrBMilIcnIysrKyoNPpqhbF/FFiYiJ27tyJ0aNHV932x3MeN2/ejPfffx8DBgwAAJw9exY5OTnVHqPX6+FwOG6YaeTIkViyZAkaN24MjUaDgQMHVst7+PBhxMfH1/RLJCIiIg/AaW5B+vTpg5SUFAwdOhRr167F6dOnsWXLFrz88svYtWsXAOCZZ57Bxx9/jIULFyItLQ2vv/469u/fD0mSqp4nISEBixcvxpEjR7B9+3aMHDkSJpOp2rFiY2OxYcMGZGVlIT8//5qZRo4ciT179mDq1Km49957q53L+cILL2DLli0YP3489u7di7S0NKxcuZILcIiIiDwcy6QgkiRh9erVuP322/Hwww+jefPmeOCBB3DmzBmEh4cDqCx3L730EiZNmoTk5GSkp6dj7Nix1RazfPzxx8jPz0dycjJGjRqFCRMmICwsrNqxZs2ahXXr1iE6OhodOnS4Zqb4+Hh07twZ+/fvr1rFfVnbtm3x888/4/jx4+jevTs6dOiAV199FY0aNarDV4WIiIiURrmruT1U3759ERERgcWLF4uOckP83hEREakfz5mUsdLSUnz44Yfo168ftFotPv/8c6xfv75qn0oiIiIi0VgmZezyVPjUqVNRXl6OxMREfP311+jTp4/oaEREREQAWCZlzWQyYf369aJjEBEREV0TF+AQERERkdtYJomIiIjIbSyTREREROQ2lkkiIiIichvLJBERERG5jWWSiIiIiNzGMqlQqampkCQJBQUF131cbGws5syZ0yCZiIiIyPModp/JNgvbNOjxDow50KDHu5EuXbogMzMT/v7+AIAFCxZg4sSJV5TLnTt3wmw2C0hIREREnkCxZdLTGQwGRERE3PBxoaGhDZCGiIiIPBWnuetRz549MX78eIwfPx7+/v4ICQnBK6+8ApfLBQDIz8/H6NGjERgYCG9vb9x1111IS0ur+vwzZ85g8ODBCAwMhNlsRqtWrbB69WoA1ae5U1NT8fDDD6OwsBCSJEGSJEyePBlA9WnuESNG4P7776+W0WazISQkBIsWLQIAOJ1OTJ8+HXFxcTCZTGjXrh2++uqren6liIiISKlYJuvZwoULodPpsGPHDrzzzjt4++238dFHHwEAxo4di127duHbb7/F1q1b4XK5MGDAANhsNgDA008/jYqKCvzyyy84cOAA3nzzTfj4+FxxjC5dumDOnDnw8/NDZmYmMjMzMWnSpCseN3LkSHz33XewWCxVt/34448oLS3FsGHDAADTp0/HokWL8OGHH+LQoUP4y1/+goceegg///xzfbw8REREpHCc5q5n0dHRmD17NiRJQmJiIg4cOIDZs2ejZ8+e+Pbbb7F582Z06dIFALBkyRJER0djxYoVGD58ODIyMnDPPfegTZvK80ObNm161WMYDAb4+/tDkqTrTn3369cPZrMZy5cvx6hRowAAn332Ge6++274+vqioqIC06ZNw/r165GSklJ1zE2bNmH+/Pno0aNHXb40REREpAIcmaxnt912GyRJqvo4JSUFaWlpOHz4MHQ6HW699daq+4KDg5GYmIgjR44AACZMmIDXX38dXbt2xWuvvYb9+/ffVBadTof77rsPS5YsAQCUlJRg5cqVGDlyJADgxIkTKC0tRd++feHj41P1Z9GiRTh58uRNHZuIiIjUiSOTMjZu3Dj069cPq1atwtq1azF9+nTMmjULzzzzjNvPOXLkSPTo0QPZ2dlYt24dTCYT+vfvDwBV09+rVq1CVFRUtc8zGo3ufyFERESkWhyZrGfbt2+v9vG2bduQkJCApKQk2O32avfn5ubi2LFjSEpKqrotOjoaTz75JL755hv89a9/xX/+85+rHsdgMMDhcNwwT5cuXRAdHY1ly5ZhyZIlGD58OPR6PQAgKSkJRqMRGRkZiI+Pr/YnOjranS+fiIiIVI4jk/UsIyMDzz33HJ544gns2bMH7777LmbNmoWEhAQMGTIEjz32GObPnw9fX1+8+OKLiIqKwpAhQwAAEydOxF133YXmzZsjPz8fGzduRMuWLa96nNjYWFgsFmzYsAHt2rWDt7c3vL29r/rYESNG4MMPP8Tx48excePGqtt9fX0xadIk/OUvf4HT6US3bt1QWFiIzZs3w8/PD2PGjKn7F4iIiIgUjSOT9Wz06NEoKytD586d8fTTT+PZZ5/F448/DgD45JNPcMstt2DQoEFISUmBy+XC6tWrq0YKHQ4Hnn76abRs2RL9+/dH8+bN8f7771/1OF26dMGTTz6J+++/H6GhoZgxY8Y1M40cORKHDx9GVFQUunbtWu2+KVOm4JVXXsH06dOrjrtq1SrExcXV0StCREREaiK5Lm96KFPl5eVIT09HXFwcvLy8RMeplZ49e6J9+/YeezlDJX/viIiIqGY4MklEREREbmOZJCIiIiK3cQFOPUpNTRUdgYiIiKhecWSSiIiIiNymmDIp83VCdBX8nhEREamf7Mvk5W1ySktLBSeh2rr8Pbv8PSQiIiL1kf05k1qtFgEBAcjOzgYAeHt7V7vWNcmPy+VCaWkpsrOzERAQAK1WKzoSERER1RPZ7zMJVJaTrKwsFBQUiI5CtRAQEICIiAiWfyIiIhVTRJm8zOFwwGaziY5BNaDX6zkiSURE5AEUVSaJiIiISF5kvwCHiIiIiOSLZZKIiIiI3MYySURERERuY5kkIiIiIrexTBIRERGR21gmiYiIiMhtLJNERERE5DaWSSIiIiJyG8skEREREbmNZZKIiIiI3MYySURERERuY5kkIiIiIrexTBIRERGR21gmiYiIiMht/w8jQJixGKw3NgAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 800x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "full_counts.plot.pie(figsize=(8, 8), subplots=True, autopct='%1.1f%%')\n",
    "plt.ylabel('')\n",
    "plt.legend(loc='lower left')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "67bda5c6",
   "metadata": {},
   "outputs": [],
   "source": [
    "sentiment_map = {\n",
    "    'negative': 0,\n",
    "    'neautral': 1,\n",
    "    'positive': 2\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "11d34a89",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>review</th>\n",
       "      <th>sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>71368</th>\n",
       "      <td>Очень высокая талия и тугая резинка, в остальн...</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>83060</th>\n",
       "      <td>супер как всегда</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>44341</th>\n",
       "      <td>в описании указан хлопок, на этикетке 65%полиэ...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11706</th>\n",
       "      <td>Не получил . Вёл спор спор закрыли с возвратом...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>45829</th>\n",
       "      <td>не дошёл. видимо наша почта. было два заказа о...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5373</th>\n",
       "      <td>Толстовка пришла примерно за 1,5 месяца до Арх...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>54297</th>\n",
       "      <td>Пижама пришла с дырками, а так качество хороше...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>31163</th>\n",
       "      <td>выбрала не тот размер - s,  так как рукава нач...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>62551</th>\n",
       "      <td>Прислали не тот цвет. Заказывала серый, а прис...</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>48628</th>\n",
       "      <td>Размер маленький, заказала м, пришла хl</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                  review  sentiment\n",
       "71368  Очень высокая талия и тугая резинка, в остальн...          2\n",
       "83060                                   супер как всегда          2\n",
       "44341  в описании указан хлопок, на этикетке 65%полиэ...          1\n",
       "11706  Не получил . Вёл спор спор закрыли с возвратом...          0\n",
       "45829  не дошёл. видимо наша почта. было два заказа о...          1\n",
       "5373   Толстовка пришла примерно за 1,5 месяца до Арх...          0\n",
       "54297  Пижама пришла с дырками, а так качество хороше...          1\n",
       "31163  выбрала не тот размер - s,  так как рукава нач...          1\n",
       "62551  Прислали не тот цвет. Заказывала серый, а прис...          2\n",
       "48628            Размер маленький, заказала м, пришла хl          1"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reviews.sentiment = reviews.sentiment.apply(lambda x: sentiment_map[x])\n",
    "reviews.sample(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "a3e31fd2",
   "metadata": {},
   "outputs": [],
   "source": [
    "train, test = train_test_split(reviews, test_size=0.2, random_state=42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "4f963d51",
   "metadata": {},
   "outputs": [],
   "source": [
    "task = Task('multiclass', loss='f1')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c9819548",
   "metadata": {},
   "outputs": [],
   "source": [
    "automl = TabularNLPAutoML(\n",
    "    task=task,\n",
    "    gpu_ids='0',\n",
    "    general_params={\n",
    "        'nested_cv': False,\n",
    "        'use_algos': [['nn', 'linear_l2', 'lgb']]\n",
    "    },\n",
    "    text_params={\n",
    "        'lang': 'ru'\n",
    "    },\n",
    "    timeout=3600,\n",
    "    cpu_limit=4,\n",
    "    reader_params={\n",
    "        'random_state': 42\n",
    "    },\n",
    "    nn_params={\n",
    "        'opt_params': {'lr': 1e-5},\n",
    "        'max_length': 128,\n",
    "        'bs': 32,\n",
    "        'n_epochs': 7,\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "9579e198",
   "metadata": {},
   "outputs": [],
   "source": [
    "roles = {\n",
    "    'text': ['review'],\n",
    "    'target': 'sentiment'\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "cbcd9243",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12:35:58] Stdout logging level is DEBUG.\n",
      "[12:35:58] Model language mode: ru\n",
      "[12:35:58] Task: multiclass\n",
      "\n",
      "[12:35:58] Start automl preset with listed constraints:\n",
      "[12:35:58] - time: 3600.00 seconds\n",
      "[12:35:58] - CPU: 4 cores\n",
      "[12:35:58] - memory: 16 GB\n",
      "\n",
      "[12:35:58] \u001b[1mTrain data shape: (69856, 2)\u001b[0m\n",
      "\n",
      "[12:35:58] Layer \u001b[1m1\u001b[0m train process start. Time left 3599.96 secs\n",
      "[12:36:10] Start fitting \u001b[1mLvl_0_Pipe_0_Mod_0_LinearL2\u001b[0m ...\n",
      "[12:36:10] Training params: {'tol': 1e-06, 'max_iter': 100, 'cs': [1e-05, 5e-05, 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000], 'early_stopping': 2, 'categorical_idx': [], 'embed_sizes': (), 'data_size': 100}\n",
      "[12:36:10] ===== Start working with \u001b[1mfold 0\u001b[0m for \u001b[1mLvl_0_Pipe_0_Mod_0_LinearL2\u001b[0m =====\n",
      "[12:36:12] Linear model: C = 1e-05 score = -1.1005894053559164\n",
      "[12:36:13] Linear model: C = 5e-05 score = -1.1005894053559164\n",
      "[12:36:13] Linear model: C = 0.0001 score = -1.1005894053559164\n",
      "[12:36:13] ===== Start working with \u001b[1mfold 1\u001b[0m for \u001b[1mLvl_0_Pipe_0_Mod_0_LinearL2\u001b[0m =====\n",
      "[12:36:14] Linear model: C = 1e-05 score = -1.100669721580058\n",
      "[12:36:14] Linear model: C = 5e-05 score = -1.100669721580058\n",
      "[12:36:14] Linear model: C = 0.0001 score = -1.100669721580058\n",
      "[12:36:14] ===== Start working with \u001b[1mfold 2\u001b[0m for \u001b[1mLvl_0_Pipe_0_Mod_0_LinearL2\u001b[0m =====\n",
      "[12:36:15] Linear model: C = 1e-05 score = -1.100528858114199\n",
      "[12:36:15] Linear model: C = 5e-05 score = -1.100528858114199\n",
      "[12:36:15] Linear model: C = 0.0001 score = -1.100528858114199\n",
      "[12:36:16] Fitting \u001b[1mLvl_0_Pipe_0_Mod_0_LinearL2\u001b[0m finished. score = \u001b[1m-1.1005959949223922\u001b[0m\n",
      "[12:36:16] \u001b[1mLvl_0_Pipe_0_Mod_0_LinearL2\u001b[0m fitting and predicting completed\n",
      "[12:36:16] Time left 3582.03 secs\n",
      "\n",
      "[12:36:18] Feature concated__review fitted\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|                                                                                          | 0/219 [00:00<?, ?it/s]C:\\Users\\Admin\\.conda\\envs\\oldervenv\\Lib\\site-packages\\transformers\\models\\bert\\modeling_bert.py:435: UserWarning: 1Torch was not compiled with flash attention. (Triggered internally at ..\\aten\\src\\ATen\\native\\transformers\\cuda\\sdp_utils.cpp:455.)\n",
      "  attn_output = torch.nn.functional.scaled_dot_product_attention(\n",
      "100%|████████████████████████████████████████████████████████████████████████████████| 219/219 [10:02<00:00,  2.75s/it]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12:46:22] Feature concated__review transformed\n",
      "[12:46:23] Start fitting \u001b[1mLvl_0_Pipe_1_Mod_0_LightGBM\u001b[0m ...\n",
      "[12:46:23] Training params: {'task': 'train', 'learning_rate': 0.03, 'num_leaves': 64, 'feature_fraction': 0.7, 'bagging_fraction': 0.7, 'bagging_freq': 1, 'max_depth': -1, 'verbosity': -1, 'reg_alpha': 1, 'reg_lambda': 0.0, 'min_split_gain': 0.0, 'zero_as_missing': False, 'num_threads': 4, 'max_bin': 255, 'min_data_in_bin': 3, 'num_trees': 1200, 'early_stopping_rounds': 200, 'random_state': 42}\n",
      "[12:46:23] ===== Start working with \u001b[1mfold 0\u001b[0m for \u001b[1mLvl_0_Pipe_1_Mod_0_LightGBM\u001b[0m =====\n",
      "[12:46:28] Training until validation scores don't improve for 200 rounds\n",
      "[12:47:10] [100]\tvalid's multi_logloss: 0.000931622\n",
      "[12:47:52] [200]\tvalid's multi_logloss: -1.32558\n",
      "[12:48:16] [300]\tvalid's multi_logloss: -1.87358\n",
      "[12:48:25] [400]\tvalid's multi_logloss: -2.21284\n",
      "[12:48:31] [500]\tvalid's multi_logloss: -2.46601\n",
      "[12:48:37] [600]\tvalid's multi_logloss: -2.6714\n",
      "[12:48:42] [700]\tvalid's multi_logloss: -2.83868\n",
      "[12:48:47] [800]\tvalid's multi_logloss: -2.98166\n",
      "[12:48:53] [900]\tvalid's multi_logloss: -3.1061\n",
      "[12:48:58] [1000]\tvalid's multi_logloss: -3.21628\n",
      "[12:49:03] [1100]\tvalid's multi_logloss: -3.3146\n",
      "[12:49:08] [1200]\tvalid's multi_logloss: -3.40325\n",
      "[12:49:08] Did not meet early stopping. Best iteration is:\n",
      "[1200]\tvalid's multi_logloss: -3.40325\n",
      "[12:49:13] ===== Start working with \u001b[1mfold 1\u001b[0m for \u001b[1mLvl_0_Pipe_1_Mod_0_LightGBM\u001b[0m =====\n",
      "[12:49:19] Training until validation scores don't improve for 200 rounds\n",
      "[12:50:02] [100]\tvalid's multi_logloss: -0.136374\n",
      "[12:50:43] [200]\tvalid's multi_logloss: -1.28294\n",
      "[12:51:07] [300]\tvalid's multi_logloss: -1.87084\n",
      "[12:51:17] [400]\tvalid's multi_logloss: -2.21705\n",
      "[12:51:24] [500]\tvalid's multi_logloss: -2.47418\n",
      "[12:51:29] [600]\tvalid's multi_logloss: -2.67587\n",
      "[12:51:35] [700]\tvalid's multi_logloss: -2.84226\n",
      "[12:51:40] [800]\tvalid's multi_logloss: -2.98446\n",
      "[12:51:46] [900]\tvalid's multi_logloss: -3.10806\n",
      "[12:51:51] [1000]\tvalid's multi_logloss: -3.21743\n",
      "[12:51:56] [1100]\tvalid's multi_logloss: -3.31585\n",
      "[12:52:01] [1200]\tvalid's multi_logloss: -3.40383\n",
      "[12:52:01] Did not meet early stopping. Best iteration is:\n",
      "[1200]\tvalid's multi_logloss: -3.40383\n",
      "[12:52:07] ===== Start working with \u001b[1mfold 2\u001b[0m for \u001b[1mLvl_0_Pipe_1_Mod_0_LightGBM\u001b[0m =====\n",
      "[12:52:12] Training until validation scores don't improve for 200 rounds\n",
      "[12:52:57] [100]\tvalid's multi_logloss: 0.453623\n",
      "[12:53:42] [200]\tvalid's multi_logloss: -0.999862\n",
      "[12:54:09] [300]\tvalid's multi_logloss: -1.79453\n",
      "[12:54:19] [400]\tvalid's multi_logloss: -2.20455\n",
      "[12:54:26] [500]\tvalid's multi_logloss: -2.48172\n",
      "[12:54:32] [600]\tvalid's multi_logloss: -2.68755\n",
      "[12:54:38] [700]\tvalid's multi_logloss: -2.85419\n",
      "[12:54:43] [800]\tvalid's multi_logloss: -2.99623\n",
      "[12:54:48] [900]\tvalid's multi_logloss: -3.11982\n",
      "[12:54:54] [1000]\tvalid's multi_logloss: -3.22927\n",
      "[12:54:59] [1100]\tvalid's multi_logloss: -3.32756\n",
      "[12:55:04] [1200]\tvalid's multi_logloss: -3.41612\n",
      "[12:55:04] Did not meet early stopping. Best iteration is:\n",
      "[1200]\tvalid's multi_logloss: -3.41612\n",
      "[12:55:10] Fitting \u001b[1mLvl_0_Pipe_1_Mod_0_LightGBM\u001b[0m finished. score = \u001b[1m-1.1660717776084737\u001b[0m\n",
      "[12:55:10] \u001b[1mLvl_0_Pipe_1_Mod_0_LightGBM\u001b[0m fitting and predicting completed\n",
      "[12:55:10] Time left 2448.01 secs\n",
      "\n",
      "[12:55:10] number of text features: 1 \n",
      "[12:55:10] number of categorical features: 0 \n",
      "[12:55:10] number of continuous features: 0 \n",
      "[12:55:10] Start fitting \u001b[1mLvl_0_Pipe_2_Mod_0_TorchNN__linear_layer_0\u001b[0m ...\n",
      "[12:55:10] Training params: {'num_workers': 4, 'pin_memory': False, 'max_length': 128, 'is_snap': False, 'input_bn': False, 'max_emb_size': 50, 'bert_name': None, 'pooling': 'cls', 'device': device(type='cuda', index=0), 'use_cont': True, 'use_cat': True, 'use_text': True, 'lang': 'ru', 'deterministic': False, 'multigpu': False, 'random_state': 42, 'model': '_linear_layer', 'model_with_emb': False, 'path_to_save': None, 'verbose_inside': None, 'verbose': 1, 'n_epochs': 7, 'snap_params': {'k': 1, 'early_stopping': True, 'patience': 1, 'swa': False}, 'bs': 32, 'emb_dropout': 0.1, 'emb_ratio': 3, 'opt': <class 'torch.optim.adam.Adam'>, 'opt_params': {'lr': 1e-05}, 'sch': <class 'torch.optim.lr_scheduler.ReduceLROnPlateau'>, 'scheduler_params': {'patience': 5, 'factor': 0.5, 'verbose': True}, 'loss': None, 'loss_params': {}, 'loss_on_logits': True, 'clip_grad': False, 'clip_grad_params': {}, 'init_bias': True, 'dataset': <class 'lightautoml.text.nn_model.UniversalDataset'>, 'tuned': False, 'optimization_search_space': None, 'verbose_bar': False, 'freeze_defaults': False, 'n_out': 3, 'hid_factor': [2, 2], 'hidden_size': [512, 512, 512], 'block_config': [2, 2], 'compression': 0.5, 'growth_size': 256, 'bn_factor': 2, 'drop_rate': 0.1, 'noise_std': 0.05, 'num_init_features': None, 'act_fun': <class 'torch.nn.modules.activation.ReLU'>, 'use_noise': False, 'use_bn': True, 'embedding_size': 10, 'cat_embedder': 'cat', 'cont_embedder': 'cont', 'stop_by_metric': False, 'device_ids': None, 'num_dims': 0, 'text_features': ['concated__review'], 'bias': array([-1.09109651, -1.11176819, -1.09310185])}\n",
      "[12:55:10] ===== Start working with \u001b[1mfold 0\u001b[0m for \u001b[1mLvl_0_Pipe_2_Mod_0_TorchNN__linear_layer_0\u001b[0m =====\n",
      "[12:55:12] Last linear layer not founded, so init_bias=False\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Admin\\.conda\\envs\\oldervenv\\Lib\\site-packages\\torch\\optim\\lr_scheduler.py:28: UserWarning: The verbose parameter is deprecated. Please use get_last_lr() to access the learning rate.\n",
      "  warnings.warn(\"The verbose parameter is deprecated. Please use get_last_lr() \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[13:09:03] Epoch: 0, train loss: -0.5600939393043518, val loss: -0.5802683234214783, val metric: -0.5708573700281828\n",
      "[13:22:44] Epoch: 1, train loss: -0.5782846808433533, val loss: -0.5825074315071106, val metric: -0.575445364816219\n",
      "[13:36:50] Epoch: 2, train loss: -0.5920115113258362, val loss: -0.5812731981277466, val metric: -0.5949136811340022\n",
      "[13:36:53] Time limit exceeded after calculating fold 0\n",
      "\n",
      "[13:36:53] Fitting \u001b[1mLvl_0_Pipe_2_Mod_0_TorchNN__linear_layer_0\u001b[0m finished. score = \u001b[1m-0.5949136811340022\u001b[0m\n",
      "[13:36:53] \u001b[1mLvl_0_Pipe_2_Mod_0_TorchNN__linear_layer_0\u001b[0m fitting and predicting completed\n",
      "[13:36:53] Time left -55.41 secs\n",
      "\n",
      "[13:36:53] Time limit exceeded. Last level models will be blended and unused pipelines will be pruned.\n",
      "\n",
      "[13:36:53] \u001b[1mLayer 1 training completed.\u001b[0m\n",
      "\n",
      "[13:36:53] Blending: optimization starts with equal weights and score \u001b[1m-0.7805581364508196\u001b[0m\n",
      "[13:36:53] Blending: iteration \u001b[1m0\u001b[0m: score = \u001b[1m-0.7118186606904026\u001b[0m, weights = \u001b[1m[0.05511818 0.18094979 0.76393205]\u001b[0m\n",
      "[13:36:54] Blending: iteration \u001b[1m1\u001b[0m: score = \u001b[1m-0.7112453960186366\u001b[0m, weights = \u001b[1m[0.05007562 0.18599236 0.76393205]\u001b[0m\n",
      "[13:36:54] Blending: iteration \u001b[1m2\u001b[0m: score = \u001b[1m-0.7112453960186366\u001b[0m, weights = \u001b[1m[0.05007562 0.18599236 0.76393205]\u001b[0m\n",
      "[13:36:54] Blending: no score update. Terminated\n",
      "\n",
      "[13:36:54] \u001b[1mAutoml preset training completed in 3656.83 seconds\u001b[0m\n",
      "\n",
      "[13:36:54] Model description:\n",
      "Final prediction for new objects (level 0) = \n",
      "\t 0.05008 * (3 averaged models Lvl_0_Pipe_0_Mod_0_LinearL2) +\n",
      "\t 0.18599 * (3 averaged models Lvl_0_Pipe_1_Mod_0_LightGBM) +\n",
      "\t 0.76393 * (1 averaged models Lvl_0_Pipe_2_Mod_0_TorchNN__linear_layer_0) \n",
      "\n",
      "CPU times: total: 1h 25min 4s\n",
      "Wall time: 1h 56s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "oof_predict = automl.fit_predict(train, roles=roles, verbose=5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "ff74d073",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████████| 55/55 [02:42<00:00,  2.95s/it]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[13:39:44] Feature concated__review transformed\n",
      "[13:39:56] Last linear layer not founded, so init_bias=False\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Admin\\.conda\\envs\\oldervenv\\Lib\\site-packages\\torch\\optim\\lr_scheduler.py:28: UserWarning: The verbose parameter is deprecated. Please use get_last_lr() to access the learning rate.\n",
      "  warnings.warn(\"The verbose parameter is deprecated. Please use get_last_lr() \"\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[0.10684817, 0.8097664 , 0.08338545],\n",
       "       [0.07052832, 0.08103839, 0.84843326],\n",
       "       [0.25625676, 0.65766203, 0.08608122],\n",
       "       ...,\n",
       "       [0.2176136 , 0.6060892 , 0.17629725],\n",
       "       [0.7403015 , 0.15933894, 0.1003596 ],\n",
       "       [0.19385871, 0.71585095, 0.09029038]], dtype=float32)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%time\n",
    "test_pred = automl.predict(test)\n",
    "test_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "6e4fba0e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 1, ..., 1, 0, 1], dtype=int64)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predictied_labels = np.argmax(test_pred.data, axis=1)\n",
    "predictied_labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "cffe96e2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7765244775264816"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "accuracy_score(predictied_labels, test['sentiment'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "743b0d95",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7785341403489191"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f1_score(test['sentiment'], predictied_labels, average='macro')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "939443ea",
   "metadata": {},
   "outputs": [],
   "source": [
    "lime = LimeTextExplainer(automl, feature_selection='lasso', force_order=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "10c96f7a",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████████| 16/16 [00:58<00:00,  3.68s/it]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[13:42:32] Feature concated__review transformed\n",
      "[13:42:37] Last linear layer not founded, so init_bias=False\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Admin\\.conda\\envs\\oldervenv\\Lib\\site-packages\\torch\\optim\\lr_scheduler.py:28: UserWarning: The verbose parameter is deprecated. Please use get_last_lr() to access the learning rate.\n",
      "  warnings.warn(\"The verbose parameter is deprecated. Please use get_last_lr() \"\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "    <div>\n",
       "        <p style=\"text-align: center\">\n",
       "            Text\n",
       "        </p>\n",
       "        <div style=\"border: 1px solid black;\">\n",
       "            <p style=\"font-size:14px;; margin-left: 1%; margin-right: 1%;\"><span style=\"background-color: #FFFEFE;\">куртка</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FF7E7E;\">отличная</span> <span style=\"background-color: #FFFEFE;\">, </span> <span style=\"background-color: #FFFEFE;\">цвет</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">глубокий</span> <span style=\"background-color: #FFFEFE;\">, </span> <span style=\"background-color: #FFD0D0;\">насыщенный</span> <span style=\"background-color: #FFFEFE;\">. в 5 </span> <span style=\"background-color: #FFFEFE;\">градусов</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">уже</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">хочется</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">одеть</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">кофточку</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">под</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">низ</span> <span style=\"background-color: #FFFEFE;\">. </span> <span style=\"background-color: #FFFEFE;\">брала</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">чтобы</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">ездить</span> <span style=\"background-color: #FFFEFE;\"> с </span> <span style=\"background-color: #FFFEFE;\">ней</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">по</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">лесам</span> <span style=\"background-color: #FFFEFE;\">, </span> <span style=\"background-color: #FFFEFE;\">ну</span> <span style=\"background-color: #FFFEFE;\"> и </span> <span style=\"background-color: #FFFEFE;\">так</span> <span style=\"background-color: #FFFEFE;\">, в </span> <span style=\"background-color: #FFFEFE;\">городе</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">за</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">хлебом</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">сбегать</span> <span style=\"background-color: #FFFEFE;\"> - </span> <span style=\"background-color: #FFFEFE;\">эти</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">потребности</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">полностью</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFDADA;\">удовлетворены</span> <span style=\"background-color: #FFFEFE;\">) </span> <span style=\"background-color: #FFFEFE;\">нитки</span> <span style=\"background-color: #FFFEFE;\"> и </span> <span style=\"background-color: #FFFEFE;\">пушинки</span> <span style=\"background-color: #FFFEFE;\"> </span> <span style=\"background-color: #FFFEFE;\">особо</span> <span style=\"background-color: #FFFEFE;\"> не торчат, запаха нет. качество хорошее, но хотелось бы немного потеплее. на постоянной 168, ог 87, об 89 взяла размер м, что хорошо - выглядит аккуратно, можно пододеть что то. думаю размер s был бы тоже норм, но без опции утепления</span> <span style=\"background-color: #FFD6D6;\">неторчат</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">запаха</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">нет</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">качество</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFCECE;\">хорошее</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">но</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">хотелось</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">бы</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">немного</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFD0D0;\">потеплее</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">на</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFD3D3;\">постоянной</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">ог</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">об</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">взяла</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFC6C6;\">размер</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">что</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFDADA;\">хорошо</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFD6D6;\">выглядит</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">аккуратно</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">можно</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">пододеть</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">что</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">то</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">думаю</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFC6C6;\">размер</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">был</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">бы</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">тоже</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">норм</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">но</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">без</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">опции</span> <span style=\"background-color: #FFFEFE;\"></span> <span style=\"background-color: #FFFEFE;\">утепления</span> <span style=\"background-color: #FFFEFE;\"></span></p>\n",
       "        </div>\n",
       "        \n",
       "        <p style=\"text-align: center\">\n",
       "            Class mapping\n",
       "        </p>\n",
       "        <div style=\"margin-left: 10%; margin-right: 10%; \">\n",
       "            <div id=\"grad\" style=\"background: linear-gradient(90deg, #FF7E7E 0%, #FFFEFE 50%, #8080FF 100%); border: 1px solid black; margin-left: 1.5em; margin-right: 1.5em; float: center; \">\n",
       "                <p style=\"text-align:left; margin-left: 1%; margin-right: 1%; color: white;\">\n",
       "                    Other classes\n",
       "                    <span style=\"float:right;\">\n",
       "                        Class: 1\n",
       "                    </span>\n",
       "                </p>\n",
       "            </div>\n",
       "\n",
       "            <div style=\"margin-left: 1.5em; margin-right: 1.5em; \">\n",
       "                <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -1.085em\">-3.1</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -1.085em\">-2.5</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -1.085em\">-1.8</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -1.085em\">-1.2</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -1.085em\">-0.6</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -0.7em\">0.0</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -0.7em\">0.6</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -0.7em\">1.2</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -0.7em\">1.8</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 9.97%;\"><span style=\"position: relative; top: 1em; left: -0.7em\">2.5</span></div> <div style=\"border-left: 1px solid black; height: 18px; float: left; width: 0%;\"><span style=\"position: relative; top: 1em; left: -0.7em\">3.1</span></div>\n",
       "            </div>\n",
       "\n",
       "            <div style=\"float: right; right: 0.75em; top: -3em; position: relative; font-weight: bold;\"></div>\n",
       "            <div style=\"float: right; right: -2em; top: -2.9em; position: relative; font-weight: bold;\"></div>\n",
       "\n",
       "            <div style=\"float: left; left: -5.5em; top: -4.42em; position: relative;  font-weight: bold;\"></div>\n",
       "            <div style=\"float: left; left: -8.22em; top: -2.9em; position: relative;  font-weight: bold;\"></div>\n",
       "        </div>\n",
       "        \n",
       "    </div>\n",
       "    "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "exp = lime.explain_instance(test.iloc[42], labels=(0, 1, 2), perturb_column='review')\n",
    "exp.visualize_in_notebook(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "e8bedab1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predictied_labels[42]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "a5d07d19",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "review       куртка отличная, цвет глубокий, насыщенный. в ...\n",
       "sentiment                                                    2\n",
       "Name: 79206, dtype: object"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test.iloc[42]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "235e4553",
   "metadata": {},
   "source": [
    "## Сохранение модели"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "c83d0b22",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle\n",
    "\n",
    "with open('models/small_text_lama_classifier.pkl', 'wb') as f:\n",
    "    pickle.dump(automl, f)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "365028ee",
   "metadata": {},
   "source": [
    "## Загрузка и повторное тестирование модели"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "7d7dddd5",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('models/small_text_lama_classifier.pkl', 'rb') as f:\n",
    "    loaded_automl = pickle.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "90ae2308",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████████| 55/55 [02:42<00:00,  2.96s/it]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[14:00:52] Feature concated__review transformed\n",
      "[14:01:06] Last linear layer not founded, so init_bias=False\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Admin\\.conda\\envs\\oldervenv\\Lib\\site-packages\\torch\\optim\\lr_scheduler.py:28: UserWarning: The verbose parameter is deprecated. Please use get_last_lr() to access the learning rate.\n",
      "  warnings.warn(\"The verbose parameter is deprecated. Please use get_last_lr() \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: total: 4min 32s\n",
      "Wall time: 4min 35s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[0.10684817, 0.8097664 , 0.08338545],\n",
       "       [0.07052832, 0.08103839, 0.84843326],\n",
       "       [0.25625676, 0.65766203, 0.08608122],\n",
       "       ...,\n",
       "       [0.2176136 , 0.6060892 , 0.17629725],\n",
       "       [0.7403015 , 0.15933894, 0.1003596 ],\n",
       "       [0.19385871, 0.71585095, 0.09029038]], dtype=float32)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%time\n",
    "test_pred = automl.predict(test)\n",
    "test_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "ad4306f9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 1, ..., 1, 0, 1], dtype=int64)"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predictied_labels = np.argmax(test_pred.data, axis=1)\n",
    "predictied_labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "a9643d3c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7765244775264816"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "accuracy_score(predictied_labels, test['sentiment'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "f01eb28b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7785341403489191"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f1_score(test['sentiment'], predictied_labels, average='macro')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py311",
   "language": "python",
   "name": "py311"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
